#include "Server.h"

#include "../../Common.h"

#include <QList>

#define RECIEVED_DATA_MAX_SIZE  4096
#define DATA_CACHE_MAX_SIZE     2048    //接受的最大缓存数据(用来找包头),如果超过则释放掉
#define TRANSMITS_CODE_COUNT    20      //


_SetGroupExtraDataCallback _ClientsGroupInfo::SetGroupExtraDataCallback = nullptr;
_UnsetGroupExtraDataCallback _ClientsGroupInfo::UnsetGroupExtraDataCallback = nullptr;
_InitGroupExtraDataCallback _ClientsGroupInfo::InitGroupExtraDataCallback = nullptr;
_ReleaseGroupExtraDataCallback _ClientsGroupInfo::ReleaseGroupExtraDataCallback = nullptr;




int _ClientsGroupInfo::ReJoinRunningGroup(_ClientInfo* pClientInfo, qint32 groupIndex)//QUuid id)
{
    if(m_mapDisconnectClientData.contains(groupIndex))
    {
        qCritical() << "[!Server]ERROR:ReJoinRunningGroup:" << groupIndex;
        return -1;
    }
    else if(m_stackClientIndex.contains(groupIndex))
    {
        qCritical() << "[!Server]ERROR:ReJoinRunningGroup1:" << groupIndex;
        return -2;
    }

    pClientInfo->m_pGroup = this;
    m_mapAllClients.insert(pClientInfo->m_SocketContext.nSocketID, pClientInfo);
    m_mapPlayingClients.insert(pClientInfo->m_SocketContext.nSocketID, pClientInfo);
    pClientInfo->m_nIndex = groupIndex;

    return 0;
}

int _ClientsGroupInfo::SendToGroupAllClients(QByteArray ba, _ClientInfo *pClientInfo, int type)
{
    QMap<qint32, _ClientInfo*>::const_iterator ii;

    if(type == -1)
    {
        for(ii = m_mapAllClients.constBegin(); ii != m_mapAllClients.constEnd(); ++ii)
        {
            if((*ii) != pClientInfo)
                m_pIOCP->send((*ii)->m_SocketContext, ba);
        }
    }
    else if(type == 0)
    {
        for(ii = m_mapWatchingClients.constBegin(); ii != m_mapWatchingClients.constEnd(); ++ii)
        {
            if((*ii) != pClientInfo)
                m_pIOCP->send((*ii)->m_SocketContext, ba);
        }
    }
    else
    {
        {
            for(ii = m_mapPlayingClients.constBegin(); ii != m_mapPlayingClients.constEnd(); ++ii)
            {
                if((*ii) != pClientInfo)
                    m_pIOCP->send((*ii)->m_SocketContext, ba);
            }
        }
    }

    qDebug() << "[Group]所有群组发送数据完毕";
    return 0;
}

QDataStream& operator<<(QDataStream &ds, const _ClientsGroupInfo::_RandomNumber &r)
{
    ds << r.m_nRandomNumberID << r.m_listRandomNumber << r.m_nUsePoint;
    return ds;
}
QDataStream& operator>>(QDataStream &ds, _ClientsGroupInfo::_RandomNumber &r)
{
    ds >> r.m_nRandomNumberID >> r.m_listRandomNumber >> r.m_nUsePoint;
    return ds;
}









Server::Server(QObject *parent) :
    QObject(parent)
{
    qRegisterMetaType<_SocketInfo::_SocketContext>("_SocketInfo::_SocketContext");


    m_nRecievedDataMaxSize = RECIEVED_DATA_MAX_SIZE;
    m_nDataCacheMaxSize = DATA_CACHE_MAX_SIZE;
    m_nAcceptedCount = 0;
    m_nTransmitsCodeCount = TRANSMITS_CODE_COUNT;

    m_poolClientsGroupInfo.m_bUsingLocker = false;
    m_poolClientsGroupInfo.m_bEmptyLocker = false;


    m_pJoinGroupCallBackParam = nullptr;
    m_fnJoinGroupCallBack = nullptr;


    m_ConfigFile.readConfigFile(m_vmapConfig);
    m_txtstreamLog.setDevice(&m_fileLog);



    m_IOCPModel.create();

    m_IOCPModel.SetIOCPMessageCallback((void*)Server::Fn_IOCP_Message_Callback,this);
    //m_IOCPModel.SetIOCPDbgMessageCallback((void*)Server::Fn_IOCP_MessageDbg_Callback,this);
    m_IOCPModel.SetIOCPAcceptCallback((void*)Server::Fn_IOCP_Accept_Callback,this);
    m_IOCPModel.SetIOCPRecvCallback((void*)Server::Fn_IOCP_Recv_Callback,this);
    m_IOCPModel.SetIOCPSendCallback((void*)Server::Fn_IOCP_Send_Callback,this);
    m_IOCPModel.SetIOCPCloseCallback((void*)Server::Fn_IOCP_Close_Callback,this);

    m_IOCPModel.InitOnce();


    //m_ThreadPool.start();


    //OpenLog();




    //!server.listen(QHostAddress::Any,723);
/*
    Debug("");

    //查询所有数据
    QString strSQL = "select * from leamus_ylant_io";
    QSqlQuery sqlQuery(db);
    //sql_query.prepare(strSQL);  //有错误1/2：使用这个且
    if(!sqlQuery.exec(strSQL)) //有错误2/2：忽略参数
    {
        qDebug()<<"!"<<sqlQuery.lastError();
    }
    else
    {
        while(sqlQuery.next())
        {
            int id = sqlQuery.value(0).toInt();
            QString templ_name = sqlQuery.value(1).toString();
            qDebug()<<QString("Id:%1;Templ Name:%2").arg(id).arg(templ_name);
        }
    }
*/
}

Server::~Server()
{
    if(m_fileLog.isOpen())
        m_fileLog.close();

}





//找到房间,没有返回nullptr
_ClientsGroupInfo *Server::GetGroup(QUuid id)
{
    if(id.isNull())
        return nullptr;
    //if(m_mapGroups.contains(id))
    return m_mapGroups.value(id, nullptr);
}

_ClientsGroupInfo* Server::SearchGroup(_ClientInfo* pClientInfo, QString password)
{
    if(pClientInfo == nullptr)
    {
        emit s_Warning(tr("[!Server]SearchGroup pClientInfo == nullptr"));
        return nullptr;
    }
    _ClientsGroupInfo* pGroup = nullptr;
    int nClientCount = 0;       //找出房间内人最多的房间

    QList<_ClientsGroupInfo*> listGroup = m_mapGroups.values();
    int groupCount = listGroup.count();
    int endFlag = 0;
    int ii;
    if(groupCount == 0)
    {
        emit s_Debug(tr("[Server]SearchGroup groupCount == 0, %1, %2").arg(m_mapGroups.count()).arg(listGroup.count()));
        return nullptr;
    }
    else
    {
        endFlag = Random(0, groupCount);
        ii = (endFlag + 1) % groupCount;
    }
    do
    {
        if(pClientInfo->m_pGroup == listGroup.at(ii))   //跳过
            continue;

        if(listGroup.at(ii)->m_flagStatus & _ClientsGroupInfo::Status_Locked)    //锁
            continue;

        if(listGroup.at(ii)->m_mapPlayingClients.count() >= listGroup.at(ii)->m_GroupInfo.nClientsMaxCount)    //满
            continue;

        if(!listGroup.at(ii)->m_GroupInfo.strPassword.isEmpty() && listGroup.at(ii)->m_GroupInfo.strPassword != password)
            continue;

        if(m_fnJoinGroupCallBack != nullptr)
            if(m_fnJoinGroupCallBack(pClientInfo, listGroup.at(ii), m_pJoinGroupCallBackParam) == false)
                continue;

        //找出人数最多的
        if(listGroup.at(ii)->m_mapPlayingClients.count() > nClientCount)
        {
            pGroup = listGroup.at(ii);
            nClientCount = pGroup->m_mapPlayingClients.count();
        }

        //qDebug()<<"joinGroup"<<id<<pGroup;
        //break;
    }
    while (ii = (ii + 1) % groupCount, ii != endFlag);

    if(pGroup == nullptr)   //所有房间满
    {
        //emit s_Debug(_T("[Server]所有房间满!"));
    }

    return pGroup;
}

_ClientsGroupInfo* Server::SearchGroup1(_ClientInfo* pClientInfo, QString password)
{
    if(pClientInfo == nullptr)
        return nullptr;
    _ClientsGroupInfo* pGroup = nullptr;
    int nClientCount = 0;       //找出房间内人最多的房间

    QMap<QUuid,_ClientsGroupInfo*>::const_iterator ii;
    for (ii = m_mapGroups.constBegin(); ii != m_mapGroups.constEnd(); ++ii)
    {
        if(pClientInfo->m_pGroup == (*ii))  //跳过
            continue;

        if((*ii)->m_flagStatus & _ClientsGroupInfo::Status_Locked)    //锁
            continue;

        if((*ii)->m_mapPlayingClients.count() >= (*ii)->m_GroupInfo.nClientsMaxCount)    //满
            continue;

        if(!(*ii)->m_GroupInfo.strPassword.isEmpty() && (*ii)->m_GroupInfo.strPassword != password)
            continue;

        if(m_fnJoinGroupCallBack != nullptr)
            if(m_fnJoinGroupCallBack(pClientInfo, (*ii), m_pJoinGroupCallBackParam) == false)
                continue;

        //找出人数最多的
        if((*ii)->m_mapPlayingClients.count() >= nClientCount)
        {
            nClientCount = (*ii)->m_mapPlayingClients.count();
            pGroup = (*ii);
        }

        //qDebug()<<"joinGroup"<<id<<pGroup;
        //break;
    }

    if(pGroup == nullptr)   //所有房间满
    {
        //emit s_Debug(_T("[Server]所有房间满!"));
    }

    return pGroup;
}

_ClientsGroupInfo* Server::CreateGroup(qint32 clientMaxCount, qint32 clientWatchingMaxCount, QString password)
{
    //_ClientsGroupInfo *pGroup = new _ClientsGroupInfo(&this->m_IOCPModel);
    _ClientsGroupInfo *pGroup = m_poolClientsGroupInfo.getOneEmpty();
    pGroup->m_pIOCP = &this->m_IOCPModel;
    pGroup->m_GroupInfo.nClientsMaxCount = clientMaxCount;
    pGroup->m_GroupInfo.nClientsWatchingMaxCount = clientWatchingMaxCount;
    pGroup->m_GroupInfo.strPassword = password;
    m_mapGroups.insert(pGroup->m_uuid, pGroup);
    for(qint32 i = 0; i < clientMaxCount; i++)
        pGroup->m_stackClientIndex.push(i);

    //emit s_Debug(_T("[Server]创建房间:%1").arg(pGroup->m_uuid.toString()));

    return pGroup;
}

//
int Server::JoinGroup(_ClientInfo* pClientInfo, QUuid id, const QString& password, int joinType)
{
    //int ret = 0;
    if(pClientInfo == nullptr)
    {
        //emit s_Critical(_T("[!Server]pClientInfo为空!"));
        return -1;
    }

    //已经加入了房间
    if(pClientInfo->m_pGroup != nullptr)
    {
        //emit s_Warning(_T("[!Server]客户已经加入房间!"));
        return -2;
    }

    if(id.isNull())
    {
        //emit s_Critical(_T("[!Server]房间ID错误!"));
        return -3;
    }


    _ClientsGroupInfo *pGroup = GetGroup(id);
    if(pGroup == nullptr)  //没有这个房间
    {
        //emit s_Warning(_T("[!Server]查找房间失败!"));
        return -4;
    }




    //QHash<QUuid,SocketGroup*>::const_iterator ii;
    /*if(pGroup == nullptr) //随机加入
    {
        QMap<QUuid,_ClientsGroupInfo*>::const_iterator ii;
        for (ii = m_mapGroups.constBegin(); ii != m_mapGroups.constEnd(); ++ii)
        {
            if(!((*ii)->m_flagStatus & _ClientsGroupInfo::Status_Locked)    //没锁
                    && (*ii)->m_mapPlayingClients.count() < (*ii)->m_GroupInfo.nClientsMaxCount    //没满
                    && (*ii)->m_GroupInfo.strPassword.isEmpty()    //密码空
                    )
            {
                if(m_fnJoinGroupCallBack != nullptr)
                    if(m_fnJoinGroupCallBack(pClientInfo, (*ii), m_pCallBackParam) == false)
                        continue;

                pGroup = (*ii);
                //qDebug()<<"joinGroup"<<id<<pGroup;
                break;
            }
        }
        if(pGroup == nullptr)  //所有房间满
        {
            emit s_Debug(_T("[!Server]所有房间满!"));
            return -4;
        }
    }
    else    //指定房间
    */
    {
        if(pGroup->m_flagStatus & _ClientsGroupInfo::Status_Locked)   //锁
        {
            //emit s_Debug(_T("[Server]房间被锁!"));
            return -5;
        }
        if(!pGroup->m_GroupInfo.strPassword.isEmpty() && pGroup->m_GroupInfo.strPassword != password)    //密码不对
        {
            //emit s_Debug(_T("[Server]密码错误!"));
            return -6;
        }
        if(joinType == 0)
        {
            if(pGroup->m_GroupInfo.nClientsMaxCount >= 0
                    && (pGroup->m_mapPlayingClients.count() + pGroup->m_mapDisconnectClientData.count() >= pGroup->m_GroupInfo.nClientsMaxCount)   //满
                    )
            {
                //emit s_Debug(_T("[Server]房间满!"));
                //qDebug() << "pGroup->m_mapPlayingClients.count()" << pGroup->m_mapPlayingClients.count() << pGroup->m_GroupInfo.nClientsMaxCount;
                return -7;
            }
        }
        else
        {
            if(pGroup->m_GroupInfo.nClientsWatchingMaxCount >= 0 && pGroup->m_mapWatchingClients.count() >= pGroup->m_GroupInfo.nClientsWatchingMaxCount)   //满
            {
                //emit s_Debug(_T("[Server]房间满!"));
                //qDebug() << "pGroup->m_mapWatchingClients.count()" << pGroup->m_mapWatchingClients.count() << pGroup->m_GroupInfo.nClientsWatchingMaxCount;
                return -8;
            }
        }

    }

    pClientInfo->m_pGroup = pGroup;
    pGroup->m_mapAllClients.insert(pClientInfo->m_SocketContext.nSocketID, pClientInfo);
    if(joinType == 0)
    {
        pGroup->m_mapPlayingClients.insert(pClientInfo->m_SocketContext.nSocketID, pClientInfo);
        pClientInfo->m_nIndex = pGroup->m_stackClientIndex.pop();
    }
    else if(joinType == 1)
    {
        pGroup->m_mapWatchingClients.insert(pClientInfo->m_SocketContext.nSocketID, pClientInfo);
        pClientInfo->m_nIndex = -1;
    }
    else
    {
        pGroup->m_mapWatchingClients.insert(pClientInfo->m_SocketContext.nSocketID, pClientInfo);
        pClientInfo->m_nIndex = -1;
        Warning(tr("[!GameServer]JoinGroup客户改变状态错误:%1").arg(joinType));
    }

    //emit s_Debug(_T("[Server]加入房间成功:%1").arg(pGroup->m_uuid.toString()));
    return 0;
}

/*int Server::JoinGroup(_ClientInfo* pClientInfo, _ClientsGroupInfo *pGroup, const QString& password)
{
    //int ret = 0;
    if(pClientInfo == nullptr)
        return -4;

    //已经加入了房间
    if(pClientInfo->m_pGroup != nullptr)
    {
        return -1;
    }


    //QHash<QUuid,SocketGroup*>::const_iterator ii;
    if(pGroup == nullptr) //随机加入
    {
        QMap<QUuid,_ClientsGroupInfo*>::const_iterator ii;
        for (ii = m_mapGroups.constBegin(); ii != m_mapGroups.constEnd(); ++ii)
        {
            if(!((*ii)->m_flagStatus & _ClientsGroupInfo::Status_Locked)    //没锁
                    && (*ii)->m_mapPlayingClients.count() < (*ii)->m_GroupInfo.nClientsMaxCount    //没满
                    && (*ii)->m_GroupInfo.strPassword.isEmpty()    //密码空
                    )
            {
                if(m_fnJoinGroupCallBack != nullptr)
                    if(m_fnJoinGroupCallBack(pClientInfo, (*ii), m_pCallBackParam) == false)
                        continue;

                pGroup = (*ii);
                //qDebug()<<"joinGroup"<<id<<pGroup;
                break;
            }
        }
        if(pGroup == nullptr)  //所有房间满
            return -2;
    }
    else    //指定房间
    {
        if(pGroup->m_flagStatus & _ClientsGroupInfo::Status_Locked   //锁
                || pGroup->m_mapPlayingClients.count() >= pGroup->m_GroupInfo.nClientsMaxCount //满
                || pGroup->m_GroupInfo.strPassword != password)    //密码不对
            return -3;
    }

    pGroup->m_mapAllClients.insert(pClientInfo->m_SocketContext.nSocketID, pClientInfo);
    pClientInfo->m_pGroup = pGroup;

    emit s_Debug(_T("[Server]加入房间成功:%1").arg(pGroup->m_uuid.toString()));
    return 0;
}*/


int Server::ExitGroup(_ClientInfo* pClientInfo, bool bKeepGroupIndex, QVariant data)
{
    if(pClientInfo == nullptr)
        return -1;

    //判断原来是否有房间
    if(pClientInfo->m_pGroup == nullptr)
        return -2;

    //如果是群主
    //if(pClientInfo->m_pGroup->m_MasterUser == pClientInfo)
    //{
    //    return CloseGroup(pClientInfo->m_pGroup);
    //}
    //else
    {
        //存在
        int count = pClientInfo->m_pGroup->m_mapAllClients.remove(pClientInfo->m_SocketContext.nSocketID);
        if(count > 0)
        {
            if(count > 1)
                emit s_Warning(tr("[!ExitGroup]count > 1"));

            _ClientsGroupInfo *pGroup = pClientInfo->m_pGroup;
            pClientInfo->m_pGroup = nullptr;

            switch(pClientInfo->m_ClientGroupStatus)
            {
            case GroupStatus_Playing:
            case GroupStatus_ReJoining:
                if(bKeepGroupIndex)
                    pGroup->m_mapDisconnectClientData.insert(pClientInfo->m_nIndex, data);
                else
                    pGroup->m_stackClientIndex.push(pClientInfo->m_nIndex);

                //pGroup->m_stackClientIndex.push(pClientInfo->m_nIndex);
                pClientInfo->m_nIndex = -1;
                count = pGroup->m_mapPlayingClients.remove(pClientInfo->m_SocketContext.nSocketID);
                if(count != 1)
                    emit s_Warning(tr("[!ExitGroup]playing count != 1"));
                break;
            case GroupStatus_Waiting:
            case GroupStatus_Readying:
                pGroup->m_stackClientIndex.push(pClientInfo->m_nIndex);
                pClientInfo->m_nIndex = -1;
                count = pGroup->m_mapPlayingClients.remove(pClientInfo->m_SocketContext.nSocketID);
                if(count != 1)
                    emit s_Warning(tr("[!ExitGroup]playing count != 1"));
                break;
            case GroupStatus_ReadyToWatch:
            case GroupStatus_Watching:
                pClientInfo->m_nIndex = -1;
                count = pGroup->m_mapWatchingClients.remove(pClientInfo->m_SocketContext.nSocketID);
                if(count != 1)
                    emit s_Warning(tr("[!ExitGroup]watching count != 1"));
                break;
            default:
                emit s_Critical(tr("[!ExitGroup]ExitGroup ERROR:%1").arg(pClientInfo->m_ClientGroupStatus));
                //return -3;
            }

            //qSort(pGroup->m_stackClientIndex);

            if(pGroup->m_pGroupMaster == pClientInfo)
                pGroup->ChangeGroupMaster(-2);

            //emit s_Debug(_T("[Server]退出房间成功:%1").arg(pGroup->m_uuid.toString()));
            return pGroup->m_mapPlayingClients.count();
        }
        else    //不存在sock
        {
            return -4;
        }
    }
    return -5;
}

int Server::CloseGroup(_ClientsGroupInfo *pGroup)
{
    //已经加入了房间
    if(pGroup == nullptr)
        return -1;

    /*/遍历 群里客户端
    QMap<qint32, _ClientInfo*>::const_iterator ii;
    for(ii = pGroup->m_mapAllClients.constBegin(); ii != pGroup->m_mapAllClients.constEnd(); ++ii)
    {
        (*ii)->m_pGroup = nullptr;
        //(*ii)->m_flagStatus = serverUserData::Status_Normal;
    }*/

    QMap<qint32, _ClientInfo*>::const_iterator ii;
    for(ii = pGroup->m_mapAllClients.constBegin(); ii != pGroup->m_mapAllClients.constEnd(); ++ii)
    {
        int ret = ExitGroup(*ii);
        if(ret < 0)
        {
            //emit s_Critical(_T("[!Server]关闭房间出错:%1").arg(ret));
            return ret;
        }
        //(*ii)->m_flagStatus = serverUserData::Status_Normal;
    }


    //emit s_Debug(_T("[Server]关闭房间:%1").arg(pGroup->m_uuid.toString()));
    m_mapGroups.remove(pGroup->m_uuid);
    m_poolClientsGroupInfo.releaseOneUsing(pGroup);
    //delete pGroup;

    return 0;
}


/*
bool Server::SendAllGroupsInfoToClient(_ClientInfo* pClientInfo)
{

    //遍历 群里客户端
    QMap<qint32, _ClientInfo*>::const_iterator ii;
    for(ii = m_mapGroups->m_mapAllClients.constBegin(); ii != m_mapGroups->m_mapAllClients.constEnd(); ++ii)
    {

    }
    int j = 0;
    sock->sendData()<<(qint16)GAME_SERVERRESPONSE
                   <<(qint16)GAME_SERVER_GROUP_SENDALLGROUPINFOS;
    //QHash<QUuid,SocketGroup*>::const_iterator ii;
    for (ii = groupList.constBegin(); ii != groupList.constEnd(); ++ii,++j)
    {
        sock->sendData() << (qint16)j << (*ii)->id
                       <<(qint16)((*ii)->socketList.count())
                       <<(qint16)((*ii)->groupBaseinfo.groupMaxCount);
    }
    sock->sendData()<<(qint16)-1;
    sock->send();
    return true;
}

*/




bool Server::CreateTransmitsCodeAndSend(_ClientInfo *pClientInfo, int count)
{
    while(count > 0)
    {
        pClientInfo->m_listInTransfersCode << (qrand() % 10000);  //保存
        count --;
    }

    QByteArray ba = m_IOCPModel.newSendData(TRANSMIT_CODE_RECIEVED);
    QDataStream ds(&ba,QIODevice::ReadWrite);
    ds.device()->seek(ba.size());
    ds << pClientInfo->m_listInTransfersCode;
    m_IOCPModel.CorrectDataLength(ba);
    m_IOCPModel.send(pClientInfo->m_SocketContext, ba);
    qDebug() << "[Server]发送加密Code:" << pClientInfo->m_listInTransfersCode;
    return true;
}


bool Server::RecieveUseTransfersCode(_ClientInfo *pClientInfo, QByteArray &baData)
{
    QByteArray baCode;
    if(pClientInfo->m_listInTransfersCode.length() > 0)
    {
        qint16 transfersCode = pClientInfo->m_listInTransfersCode.takeFirst();
        qDebug() << _T("[GameServer]读取密码:%1").arg(QString::fromLatin1(g_listTransfersCodeData.at(transfersCode % g_listTransfersCodeData.length())));
        baCode = g_listTransfersCodeData.at(transfersCode % g_listTransfersCodeData.length());
        //showHex(baData.data(),baData.length());

        if(pClientInfo->m_listInTransfersCode.length() == 0)
            CreateTransmitsCodeAndSend(pClientInfo, m_nTransmitsCodeCount);
    }
    else
    {
        Critical("[!GameServer]CodeList为空!");
        return false;
    }


    //可以直接解密
    if(!baCode.isEmpty())   // && m_listOutTransfersCode.count() > 0)
    {
        //如果队列中有数据,拿出第一个数据
        if(!pClientInfo->m_listInCodeData.isEmpty())
        {
            if(!baData.isEmpty())
                pClientInfo->m_listInCodeData.append(baData);
            baData = pClientInfo->m_listInCodeData.takeFirst();
        }

        //showHex(ba.data(),ba.length());
        if(!baData.isEmpty())
        {
            //解密,使用循环异或
            int i;
            for(i = 0; i < baData.length(); i++)
                baData[i] = baData.at(i) ^ baCode.at(i % baCode.length());

            qDebug() << "[Server]解密完成";
            return true;


            //showHex(ba.data(),ba.length());
            //outTransfersCode = -1;
            //m_listOutTransfersCode.takeFirst();
        }
        else
        {
            qWarning() << "[!Server]WARNING:无数据解密!";
            return false;
        }
    }
    else
    {
        qDebug() << "[Server]Data加入队列,等待解密Code";
        if(!baData.isEmpty())
            pClientInfo->m_listInCodeData.append(baData);
    }

    return false;

}

int Server::onAccept(_SocketInfo::_SocketContext socketContext)
{
    _ClientInfo *pClientInfo = (_ClientInfo *)socketContext.pSocketInfo;

    m_mapAllClients[socketContext.nSocketID] = pClientInfo;

    //发送SocketID
    QByteArray ba = m_IOCPModel.newSendData(TRANSMIT_SOCKET_ID);
    QDataStream ds(&ba,QIODevice::ReadWrite);
    ds.device()->seek(ba.size());
    ds << socketContext.nSocketID;
    m_IOCPModel.CorrectDataLength(ba);
    m_IOCPModel.send(pClientInfo->m_SocketContext, ba);

    //发送n个TransmitsCode
    CreateTransmitsCodeAndSend(pClientInfo, m_nTransmitsCodeCount);
    return 0;
}
int Server::onDisconnect(int type, _SocketInfo::_SocketContext socketContext)
{
    //m_mapAllClients.removeOne(pClientInfo);
    m_mapAllClients.remove(socketContext.nSocketID);
    m_IOCPModel.ReleaseSocketContext(socketContext.pIOCPSocketContext);
    return 0;
}


















//注意:这些都是线程回调函数,不可以直接操作主线程UI!!!
void FUNCTION_CALL_TYPE Server::Fn_IOCP_Message_Callback(int level, const char *msg, void *param)
{
    QString str;
    //QDateTime::currentDateTime().toString(Qt::SystemLocaleDate).toLatin1().constData()

    switch (level)
    {
    case 0:
        str = QString("[IOCP]Info：%1")
                .arg(QString::fromLocal8Bit(msg));
        //qInfo() << str;
        emit ((Server*)param)->s_Info(str);
        break;
    case 1:
        str = QString("[IOCP]Debug：%1")
                .arg(QString::fromLocal8Bit(msg));
        //qDebug() << str;
        emit ((Server*)param)->s_Debug(str);
        break;
    case 2:
        str = QString("[!IOCP]Warning：%1")
                .arg(QString::fromLocal8Bit(msg));
        //qWarning() << str;
        emit ((Server*)param)->s_Warning(str);
        break;
    case 3:
        str = QString("[!IOCP]Critical：%1")
                .arg(QString::fromLocal8Bit(msg));
        //qCritical() << str;
        emit ((Server*)param)->s_Critical(str);
        break;
    default:
        //qFatal() << QString("[!IOCP]Fatal:%d %s").arg(level).arg(str);
        qFatal("[!IOCP]Fatal：(%d)%s", level, str.toLatin1().constData());
        break;
    }

    //((Server*)param)->m_IOCPModel.Release(msg);
}

void FUNCTION_CALL_TYPE Server::Fn_IOCP_Accept_Callback(int socketID,void *pIOCPSocketContext,void *param)
{
    _ClientInfo *pClientInfo = (_ClientInfo*)((Server*)param)->m_IOCPModel.SocketExtraData(pIOCPSocketContext);
    //pClientInfo->_pool_init();

    pClientInfo->m_SocketContext.nSocketID = socketID;
    pClientInfo->m_SocketContext.pIOCPSocketContext = pIOCPSocketContext;
    pClientInfo->m_SocketContext.pSocketInfo = pClientInfo;

    qDebug() << "[Server]Accept:New Client Coming:" << socketID << pIOCPSocketContext << pClientInfo;

    emit ((Server*)param)->s_Accept(pClientInfo->m_SocketContext);

    ((Server*)param)->m_nAcceptedCount ++;
}

void FUNCTION_CALL_TYPE Server::Fn_IOCP_Accept_Callback_Non_Pool(int socketID,void *pIOCPSocketContext,void *param)
{
    //((Server*)param)->mapClientSocket.insert(socket, new _ClientInfo);

    //鹰:尽量快速的设置SetSocketExtraData,这样Recv和Disconnect时才能保证SocketExtraData得到正确值
    _ClientInfo* pClientInfo = new _ClientInfo;
    ((Server*)param)->m_IOCPModel.SetSocketExtraData(pClientInfo, pIOCPSocketContext);

    pClientInfo->m_SocketContext.nSocketID = socketID;
    pClientInfo->m_SocketContext.pIOCPSocketContext = pIOCPSocketContext;
    pClientInfo->m_SocketContext.pSocketInfo = pClientInfo;

    qDebug() << "[Server]Accept:New Client Coming:" << socketID << pIOCPSocketContext << pClientInfo;

    emit ((Server*)param)->s_Accept(pClientInfo->m_SocketContext);

    ((Server*)param)->m_nAcceptedCount ++;

    /*  //要放在主线程里(线程不安全)

    ((Server*)param)->m_AllClientsList.append(pClientInfo);
    emit ((Server*)param)->s_Debug(QString("Accept:%1").arg((int)pIOCPSocketContext));
    */
}

void FUNCTION_CALL_TYPE Server::Fn_IOCP_Close_Callback(int type, void *pIOCPSocketContext, void *param)
{
    //type是断开类型
    qDebug() << "[Server]CloseSocket回调:" << type;
    //提前解析出来,防止被IOCP删除
    _ClientInfo *pClientInfo = (_ClientInfo*)((Server*)param)->m_IOCPModel.SocketExtraData(pIOCPSocketContext);
    pClientInfo->m_bDisconnected = true;

    //!!!在主线程中删除pClientInfo,因为还有善后处理
    emit ((Server*)param)->s_Disconnect(type, pClientInfo->m_SocketContext);


    /*  //要放在主线程里(线程不安全)
    ((Server*)param)->m_AllClientsList.removeOne(pClientInfo);
    delete pClientInfo;
    //delete ((Server*)param)->mapClientSocket.take(socket);

    emit ((Server*)param)->s_Debug(QString("[Server]CloseSocket(%1):%2").arg(type).arg((int)pIOCPSocketContext));
    */
}

void FUNCTION_CALL_TYPE Server::Fn_IOCP_Recv_Callback(void*buf,unsigned long buflen,void *pIOCPSocketContext,void*param)
{
    //((Server*)param)->m_IOCPModel.Send(socket,(char*)buf,buflen);
    //showHex((char*)buf,buflen);

    _ClientInfo *pClientInfo = (_ClientInfo*)((Server*)param)->m_IOCPModel.SocketExtraData(pIOCPSocketContext);

    qDebug() << "[Server]Recv:" << pIOCPSocketContext << pClientInfo << "recieved:" << buflen<<(char*)buf;

    pClientInfo->m_baIn.append((char*)buf, buflen);
    //char *pPacketStart = (char*)buf;
    //unsigned long ulReaded = 0;           //已经用过的(相当于指针)

    //循环处理粘包,缺包部分(鹰:目前实现的是包足够了才发送,还有一种是 大于最大值也发送 没做.)
    while(1)
    {
        //qDebug() << pClientInfo->m_dsIn.device()->bytesAvailable()
        //         << pClientInfo->m_dsIn.device()->pos();

        //pClientInfo->m_dsIn.device()->peek(pClientInfo->m_dsIn.device()->bytesAvailable());

        int packageHeaderFlagLength = ((Server*)param)->m_IOCPModel.m_baPackageHeaderFlag.length();

        //读取标志字符
        if(pClientInfo->m_nStep == 0)
        {
            if(pClientInfo->m_dsIn.device()->bytesAvailable() >= packageHeaderFlagLength)
            {
                //找到 头标志
                int index = pClientInfo->m_baIn.indexOf(((Server*)param)->m_IOCPModel.m_baPackageHeaderFlag,pClientInfo->m_dsIn.device()->pos());
                if(index >= 0)
                {
                    pClientInfo->m_dsIn.skipRawData(index - pClientInfo->m_dsIn.device()->pos() + packageHeaderFlagLength);  //释放无用的
                    pClientInfo->m_nStep = 1;
                    qDebug() << "[Server]SocketRecieved 标志:" << index << index + packageHeaderFlagLength;
                }
                else
                {
                    qDebug() << "[Server]SocketRecieved:数据中找不到标志,继续等待接收";

                    //!!!如果缓存数大于 m_nDataCacheMaxSize,则释放掉无用的数据(最多留下 packageHeaderFlagLength - 1 个字节，也就是用来识别头的最小长度)
                    if(pClientInfo->m_dsIn.device()->bytesAvailable() > ((Server*)param)->m_nDataCacheMaxSize)
                    {
                        int n = pClientInfo->m_dsIn.device()->bytesAvailable() - (packageHeaderFlagLength - 1);
                        pClientInfo->m_dsIn.skipRawData(n);
                        qDebug() << "[Server]SocketRecieved:释放无用数据:" << n << "个字节";
                    }
                    break;
                }
            }
            else break;
        }

        //读取控制字符
        //if (inBlockSize == 0 && bytesAvailable() >= sizeof(quint32))
        if(pClientInfo->m_nStep == 1)
        {
            if(pClientInfo->m_dsIn.device()->bytesAvailable() >= sizeof(quint8))
            {
                pClientInfo->m_dsIn >> pClientInfo->m_ucInControlByte;
                pClientInfo->m_nStep = 2;
                qDebug() << "[Server]SocketRecieved:控制字符:" << pClientInfo->m_ucInControlByte;
            }
            else break;

        }

        //读长度部分
        //if(pClientInfo->m_ulDataSize == 0 && pClientInfo->m_dsIn.device()->bytesAvailable() >= sizeof(unsigned long)) //没有读取过头部(长度)
        if(pClientInfo->m_nStep == 2)
        {
            if(pClientInfo->m_dsIn.device()->bytesAvailable() >= sizeof(unsigned long))
            {
                //保存剩下的长度
                quint32 t;
                pClientInfo->m_dsIn >> t;
                if(((Server*)param)->m_nRecievedDataMaxSize > 0 && t > ((Server*)param)->m_nRecievedDataMaxSize)
                {
                    pClientInfo->m_nStep = 0;
                    pClientInfo->m_dsIn.skipRawData(t);
                    qWarning() << "[!Server]SocketRecieved WARNING:数据长度超出规定值:" << t;
                }
                else
                {
                    pClientInfo->m_ulDataSize = t;    //读数据长度
                    pClientInfo->m_nStep = 3;
                    qDebug() << "[Server]SocketRecieved:数据长度:" << pClientInfo->m_ulDataSize;
                }


                if(pClientInfo->m_ulDataSize == 0)
                {
                    //pClientInfo->m_nStep = 0;    //数据长度为0,则返回第0步
                }
            }
            else break;
        }

        //读数据部分
        //if(pClientInfo->m_ulDataSize != 0 && pClientInfo->m_dsIn.device()->bytesAvailable() >= pClientInfo->m_ulDataSize)
        if(pClientInfo->m_nStep == 3)
        {
            if(pClientInfo->m_dsIn.device()->bytesAvailable() >= pClientInfo->m_ulDataSize)
            {
                //qDebug()<<pClientInfo->m_dsIn.device()->bytesAvailable();

                qDebug() << "[Server]SocketRecieved:数据读取完毕";


                //存一个完整数据到baData
                QByteArray baData(pClientInfo->m_ulDataSize, Qt::Uninitialized);
                pClientInfo->m_dsIn.readRawData(baData.data(), pClientInfo->m_ulDataSize);

                pClientInfo->m_nStep = 0;
                pClientInfo->m_ulDataSize = 0;

                //数据处理
                switch(pClientInfo->m_ucInControlByte)
                {
                //case TRANSMIT_CODE_REQUEST:    //发送n个Code
                    //((Server*)param)->createTransmitsCodeAndSend(pClientInfo, 20);
                    //break;
                case TRANSMIT_CODE_RECIEVED:      //接受到个Code（客户端处理）
                    //in >> outTransfersCode;
                    break;
                case TRANSMIT_CODE_DATA:      //放在主线程中处理（因为要发送Code，必须在主线程中处理，否则多线程错误）
                    qDebug() << "[Server]接受到加密数据";
                    emit ((Server*)param)->s_ReadyRead(baData, pClientInfo->m_ucInControlByte, pClientInfo->m_SocketContext);
                    break;
                default:
                    emit ((Server*)param)->s_ReadyRead(baData, pClientInfo->m_ucInControlByte, pClientInfo->m_SocketContext);
                    break;
                }


                /*
                int id;
                pClientInfo->m_dsIn >> id;
                emit ((Server*)param)->s_Debug(QString("包ID:%d").arg(id));
                */


                //qDebug() << "3m_dsInfo:"
                //         << pClientInfo->m_dsIn.device()->bytesAvailable()
                //         << pClientInfo->m_dsIn.device()->pos();
            }
            else break;
        }
    }

    //释放掉已经用了的数据
    pClientInfo->m_baIn.remove(0,pClientInfo->m_dsIn.device()->pos());
    pClientInfo->m_dsIn.device()->reset();

    //emit ((Server*)param)->mapClientSocket.value(socket)->pGroup;
}

void FUNCTION_CALL_TYPE Server::Fn_IOCP_Send_Callback(void*buf, unsigned long buflen, unsigned long bufTransfered, void*pIOCPSocketContext, void*param)
{
    _ClientInfo *pClientInfo = (_ClientInfo*)((Server*)param)->m_IOCPModel.SocketExtraData(pIOCPSocketContext);

    qDebug() << "[Server]Send回调:" << pClientInfo << bufTransfered << "/" << buflen << (char*)buf;

    emit ((Server*)param)->s_SendFinished(buf, buflen, pClientInfo->m_SocketContext);
    //_ClientInfo *pClientInfo = (_ClientInfo*)((Server*)param)->m_IOCPModel.SocketExtraData(pIOCPSocketContext);

    //QString str = QString("[Server]Send回调:%1/%2").arg(bufTransfered).arg(buflen);
    //emit ((Server*)param)->s_Debug(str);

    return;

    /*  发送包完整处理 放在了IOCP中，这里的Send回调函数是 已经发送完毕的完整的一个包
    if(bufTransfered == 0)
    {
        qDebug()<<"[Server]貌似断开连接?";
        return;
    }
    else if(bufTransfered > buflen)
    {
        qDebug()<<"[Server]发送过多?";
        return;
    }
    else if (bufTransfered < buflen)
    {
        qDebug()<<"[Server]继续发送!...";
        ((Server*)param)->m_IOCPModel.Send(pIOCPSocketContext, (char*)buf + bufTransfered, buflen - bufTransfered);
        return;
    }
    else
    {
        qDebug()<<"[Server]发送成功";
        return;
    }*/
}





void* FUNCTION_CALL_TYPE Server::Fn_IOCP_SetSocketExtraData_Callback()
{
    qDebug() << "[Server]Fn_IOCP_SetSocketExtraData_Callback";
    return new _ClientInfo;
}

void FUNCTION_CALL_TYPE Server::Fn_IOCP_UnsetSocketExtraData_Callback(void *pExtraData)
{
    if(pExtraData != nullptr)
    {
        qDebug() << "[Server]Fn_IOCP_UnsetSocketExtraData_Callback";
        delete (_ClientInfo*)pExtraData;
    }
    else
        qCritical() << "[!Server]UnsetSocketExtraData Callback ERROR!";
}

void FUNCTION_CALL_TYPE Server::Fn_IOCP_Init_SocketExtraData_Callback(void *pExtraData)
{
    if(pExtraData != nullptr)
    {
        qDebug() << "[Server]Fn_IOCP_Init_SocketExtraData_Callback";
        ((_ClientInfo*)pExtraData)->_pool_init();
    }
    else
        qCritical() << "[!Server]InitSocketExtraData Callback ERROR!";
}

void FUNCTION_CALL_TYPE Server::Fn_IOCP_Release_SocketExtraData_Callback(void *pExtraData)
{
    if(pExtraData != nullptr)
    {
        qDebug() << "[Server]Fn_IOCP_Release_SocketExtraData_Callback";
        ((_ClientInfo*)pExtraData)->_pool_release();
    }
    else
        qCritical() << "[!Server]ReleaseSocketExtraData Callback ERROR!";
}
